package mge.ui
{
  import __AS3__.vec.Vector;
  import flash.display.DisplayObjectContainer;
  import flash.events.KeyboardEvent;
  import flash.events.MouseEvent;
  import flash.geom.Point;
  import flash.ui.Keyboard;
  
  
  public class Input
  {
    public function Input()
    {
    }
    
    public static function RegisterListeners(_parent:DisplayObjectContainer):void
    {
      parent = _parent;
      parent.stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
      parent.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
      parent.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
      parent.stage.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
      
      parent.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
      parent.stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
    }
    
    public static const MOUSE_LBUTTON:    int = 0;
    public static const KEY_LEFT:         int = 1;
    public static const KEY_RIGHT:        int = 2;
    public static const KEY_UP:           int = 3;
    public static const KEY_DOWN:         int = 4;
    public static const KEY_NUMPAD_ADD:   int = 5;
    public static const KEY_NUMPAD_SUB:   int = 6;
    public static const KEY_NUMPAD6:      int = 7;
    public static const KEY_NUMPAD9:      int = 8;
    public static const KEY_ENTER:        int = 9;
    public static const KEY_CONTROL:      int = 10;
    
    public static const KEY_F1:            int = 11;
    public static const KEY_F2:            int = 12;
    public static const KEY_F3:            int = 13;
    public static const KEY_F4:            int = 14;
    public static const KEY_F5:            int = 15;
    public static const KEY_F6:            int = 16;
    public static const KEY_F7:            int = 17;
    public static const KEY_F8:            int = 18;
    public static const KEY_F9:            int = 19;
    public static const KEY_F10:           int = 20;
    
    public static const KEY_PAGE_DW:      int = 21;
    public static const KEY_PAGE_UP:      int = 22;
    public static const KEY_HOME:         int = 23;
    public static const KEY_END:          int = 24;
    public static const KEY_INSERT:       int = 25;
    public static const KEY_DELETE:       int = 26;
    
    public static const KEY_NUMPAD5:      int = 27;
    
    public static const KEY_1: int = 30;
    public static const KEY_2: int = 31;
    public static const KEY_3: int = 32;
    public static const KEY_4: int = 33;
    public static const KEY_5: int = 34;
    public static const KEY_6: int = 35;
    public static const KEY_7: int = 36;
    public static const KEY_8: int = 37;
    public static const KEY_9: int = 38;
    public static const KEY_0: int = 39;
    
    
    
    public static function isDown(key:int):Boolean
    {
      for (var i:int = 0; i < down.length; i++)
        if (down[i] == key) return true;
      
      return false;
    }
    
    public static function isUp(key:int):Boolean
    {
      for (var i:int = 0; i < up.length; i++)
        if (up[i] == key) return true;
      
      return false;
    }
    
    public static function isPressed(key:int):Boolean
    {
      for (var i:int = 0; i < pressed.length; i++)
        if (pressed[i] == key) return true;
      
      return false;
    }
    
    public static function update():void
    {
      up.splice(0, up.length);
      down.splice(0, down.length);
      mouseMoving = false;
    }
    
    public static function isMouseMoving():Boolean
    {
      return mouseMoving;
    }
    
    
    private static function mouseDown(e:MouseEvent):void
    {
      _keyDown(MOUSE_LBUTTON);
    }
    
    private static function mouseUp(e:MouseEvent):void
    {
      _keyUp(MOUSE_LBUTTON);
    }
    
    private static function mouseMove(e:MouseEvent):void
    {
      mousePosition.x = e.stageX;
      mousePosition.y = e.stageY;
      mouseMoving = true;
    }
    
    private static function mouseOut(e:MouseEvent):void
    {
      if (isPressed(MOUSE_LBUTTON) && e.relatedObject == null)
        mouseUp(e);
    }
    
    public static function getMousePos():Point
    {
      return mousePosition;
    }
    
    
    private static function _keyDown(myKey:int):void
    {
      if (isPressed(myKey)) return; // Avoids keyboard autorepeat
      
      down.push(myKey);
      pressed.push(myKey);
    }
    
    private static function anyKeyEvent(e:KeyboardEvent, func:Function):void
    {
      switch(e.keyCode)
      {
        case 48: func(KEY_0); break;
        case 49: func(KEY_1); break;
        case 50: func(KEY_2); break;
        case 51: func(KEY_3); break;
        case 52: func(KEY_4); break;
        case 53: func(KEY_5); break;
        case 54: func(KEY_6); break;
        case 55: func(KEY_7); break;
        case 56: func(KEY_8); break;
        case 57: func(KEY_9); break;
        
        case Keyboard.LEFT: func(KEY_LEFT); break;
        case Keyboard.RIGHT: func(KEY_RIGHT); break;
        case Keyboard.UP: func(KEY_UP); break;
        case Keyboard.DOWN: func(KEY_DOWN); break;
        case Keyboard.NUMPAD_ADD: func(KEY_NUMPAD_ADD); break;
        case Keyboard.NUMPAD_SUBTRACT: func(KEY_NUMPAD_SUB); break;
        case Keyboard.NUMPAD_6: func(KEY_NUMPAD6); break;
        case Keyboard.NUMPAD_9: func(KEY_NUMPAD9); break;
        case Keyboard.ENTER: func(KEY_ENTER); break;
        case Keyboard.F1: func(KEY_F1); break;
        case Keyboard.F2: func(KEY_F2); break;
        case Keyboard.F3: func(KEY_F3); break;
        case Keyboard.F4: func(KEY_F4); break;
        case Keyboard.F5: func(KEY_F5); break;
        case Keyboard.CONTROL: func(KEY_CONTROL); break;
        case Keyboard.PAGE_UP: func(KEY_PAGE_UP); break;
        case Keyboard.PAGE_DOWN: func(KEY_PAGE_DW); break;
        case Keyboard.INSERT: func(KEY_INSERT); break;
        case Keyboard.DELETE: func(KEY_DELETE); break;
        case Keyboard.HOME: func(KEY_HOME); break;
        case Keyboard.END: func(KEY_END); break;
        case Keyboard.NUMPAD_5: func(KEY_NUMPAD5); break;
      }
    }

    private static function keyDown(e:KeyboardEvent):void
    {
      anyKeyEvent(e, _keyDown);
    }
    
    private static function _keyUp(myKey:int):void
    {
      for (var i:int = 0; i < pressed.length; i++)
        if (pressed[i] == myKey)
        {
          pressed.splice(i--, 1);
        }
      
      up.push(myKey);
    }
    
    private static function keyUp(e:KeyboardEvent):void
    {
      anyKeyEvent(e, _keyUp);
    }
    
    private static var pressed:Vector.<int> = new Vector.<int>;
    private static var down:Vector.<int> = new Vector.<int>;
    private static var up:Vector.<int> = new Vector.<int>;
    private static var mouseMoving:Boolean;
    private static var mousePosition:Point = new Point;
    private static var parent:DisplayObjectContainer;

  }
}